package com.enba.rbacadmin.config;

import com.enba.boot.core.context.SecurityContextHolder;
import com.enba.boot.core.exception.BizException;
import com.enba.boot.core.exception.NotLoginException;
import com.enba.boot.jwt.JwtHelper;
import com.enba.boot.web.interceptor.SecurityContextInterceptorCallback;
import com.enba.boot.web.properties.WebProperties;
import com.enba.rbacadmin.annotation.NoNeedValidation;
import io.jsonwebtoken.Claims;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;

@Configuration
@Slf4j
public class SecurityContextInterceptorCallbackImpl implements SecurityContextInterceptorCallback {

  @Autowired private WebProperties webProperties;
  @Autowired private JwtHelper jwtHelper;

  @Override
  public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) {
    // 自定义拦截器逻辑
    log.info("SecurityContextInterceptorCallbackImpl preHandle");

    // 判断handler是否是HandlerMethod类型
    if (handler instanceof HandlerMethod) {
      HandlerMethod handlerMethod = (HandlerMethod) handler;
      Method method = handlerMethod.getMethod();

      // 检查方法上是否有@NoNeedValidation注解
      if (method.isAnnotationPresent(NoNeedValidation.class)) {
        return true;
      }
    }

    String requestURI = request.getRequestURI();

    // 获取请求头中的token
    String token = request.getHeader(webProperties.getHearName());
    if (StringUtils.isBlank(token)) {
      BizException.throwEx("token is null");
    }

    // 校验token
    if (!jwtHelper.validateToken(token)) {
      // 非法token 包括token过期
      NotLoginException.throwEx();
    }

    // 解析token
    Claims claims = jwtHelper.parseToken(token);

    // 用户id设置上下文中
    SecurityContextHolder.setUserId(String.valueOf(claims.get("userId")));
    SecurityContextHolder.setKeyValue("role", claims.get("role"));
    SecurityContextHolder.setKeyValue("perms", claims.get("perms"));

    return true;
  }
}
